package com.mm.learn.shopping.order.service.impl;/**
 * @author wdx
 * @create 2021-07-27 13:21
 */

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mm.learn.constant.OrderConstant;
import com.mm.learn.interceptor.CartInterceptor;
import com.mm.learn.shopping.cart.CartService;
import com.mm.learn.shopping.cart.vo.CartItem;
import com.mm.learn.shopping.cart.vo.UserInfoTo;
import com.mm.learn.shopping.order.dao.OmsOrderDao;
import com.mm.learn.shopping.order.entity.OmsOrder;
import com.mm.learn.shopping.order.service.OrderService;
import com.mm.learn.shopping.order.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author wdx
 * @date 2021年07月27日 13:21
 */
@Service
public class OrderServiceImpl  extends ServiceImpl<OmsOrderDao, OmsOrder> implements OrderService {

    private static Map<String, List<MemberAddressVo>> addressVos = new HashMap<>();

    static {
        addressVos.put("1", Arrays.asList(new MemberAddressVo(1L, 1L, "wdd", "1654654565", "456545", "河南省", "周口市", "涮回去", "小西门", "231", 1),
                new MemberAddressVo(2L, 1L, "wdd", "1654654565", "456545", "河南省", "周口市", "涮回去", "小西门", "231", 0)));
        addressVos.put("2", Arrays.asList(new MemberAddressVo(3L, 2L, "wdd11", "1554654565", "456545", "河南省", "周口市",
                        "涮回去", "小西门", "231", 1),
                new MemberAddressVo(2L, 1L, "wdd", "1654654565", "456545", "河南省", "周口市", "涮回去", "小西门", "231", 0)));
    }

    @Autowired
    CartService cartService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public OrderConfirmVo confirmOrder() {
        OrderConfirmVo confirmVo = new OrderConfirmVo();
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        //远程查询所有的收货地址  此处模拟
        List<MemberAddressVo> addressVos = OrderServiceImpl.addressVos.get(userInfoTo.getUserId().toString());
        confirmVo.setAddress(addressVos);
        //远程查询购物车所有选中的购物项
        List<CartItem> userCartItemCheck = cartService.getUserCartItemCheck();
        String s = JSONUtil.toJsonStr(userCartItemCheck);
        List<OrderItemVo> orderItemVo = JSONUtil.toList(s, OrderItemVo.class);
        confirmVo.setItems(orderItemVo);
        //获取购物项是否有库存
        List<Long> collect = orderItemVo.stream().map(w -> w.getSkuId()).collect(Collectors.toList());
        //根据商品ID查询库存
        //查询用户积分 ...
        //其他数据自动计算
        //防重令牌
        String token = UUID.randomUUID().toString().replace("-", "");
        stringRedisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX + userInfoTo.getUserId(), token, 30, TimeUnit.SECONDS);
        confirmVo.setOrderToken(token);
        return confirmVo;
    }

    @Override
    public SubmitOrderResponseVo submitOrder(OrderSubmitVo submitVo) {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        SubmitOrderResponseVo responseVo = new SubmitOrderResponseVo();
        //下单：去创建订单，验令牌，验价格，锁库存...
        //验证令牌 【令牌的对比和删除必须保证原子性】
        String orderToken = submitVo.getOrderToken();
        String script = "if redis.call('get',KEYS[1]) == ARGV[1]" +
                "then" +
                "return redis.call('del',KEYS[1])" +
                "else" +
                "return 0" +
                "end";
        //原子验证令牌和删除令牌
        Integer execute = stringRedisTemplate.execute(new DefaultRedisScript<Integer>(script, Integer.class),
                Arrays.asList(OrderConstant.USER_ORDER_TOKEN_PREFIX + userInfoTo.getUserId()),
                orderToken);
        if (execute == 0){
            //令牌验证失败
            return responseVo;
        }else {
            //令牌验证成功
            OrderCreateTo order = createOrder(submitVo);
            //验价...
            //保存订单
            //库存锁定



        }
        return responseVo;

    }

    private OrderCreateTo createOrder(OrderSubmitVo submitVo){
        OrderCreateTo createTo = new OrderCreateTo();
        //生成订单号
        String s = UUID.randomUUID().toString();
        //创建订单号
        OmsOrder order = new OmsOrder();
        order.setOrderSn(s);
        //获取收获地址消息
        MemberAddressVo addressVos = OrderServiceImpl.addressVos.get(submitVo.getAddrId()).get(0);
        return createTo;
    }
}
